package com.bf.electroplating.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bf.electroplating.mapper.PubDataHistoryMapper;
import com.bf.electroplating.pojo.entity.PubDataHistory;
import com.bf.electroplating.service.PubDataHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PubDataHistoryServiceImpl extends ServiceImpl < PubDataHistoryMapper,PubDataHistory > implements PubDataHistoryService {
	@Override
	public void savePubDataHistory ( String bId , Object object , String type ) {
		List < PubDataHistory > historyList = list ( new LambdaQueryWrapper <PubDataHistory> ()
				.eq ( PubDataHistory::getBId , bId )
				.orderByDesc ( PubDataHistory::getVersion )
		);

		PubDataHistory pubDataHistory = new PubDataHistory ();
		pubDataHistory.setBId ( bId );
		pubDataHistory.setType ( type );
		pubDataHistory.setContent ( JSONObject.toJSONString ( object ) );
		pubDataHistory.setVersion ( CollectionUtils.isEmpty (  historyList ) ? 1 : historyList.get ( 0 ).getVersion () + 1 );
		save ( pubDataHistory );
	}

	@Override
	public < T > T dataHistoryHandle ( String oldJson , String newJson , Class < T > t ) {
		T oldObject = JSON.parseObject( oldJson , t );
		T newObject = JSON.parseObject( newJson , t );
		T resultObj = null;
		try {
			// 创建新的对象，用来保存变化的属性
			resultObj = t.getConstructor().newInstance();

			// 遍历对象的字段，比较 oldObj 和 newObj 的属性值
			Field[] result = t.getDeclaredFields ();
			for (Field field : result) {
				field.setAccessible(true);

				Object oldValue = field.get(oldObject);
				Object newValue = field.get(newObject);

				if (oldValue == null && newValue == null) continue;
				// 1. 处理集合类型
				if ( oldValue instanceof List < ? > oldList && newValue instanceof List < ? > newList ) {
					// 比较集合中对象的id
					List<String> oldIds = getIdListFromObjectList(oldList);
					List<String> newIds = getIdListFromObjectList(newList);
					if ( Objects.equals(oldIds, newIds)) {
						field.set(resultObj, null);
					} else {
						field.set(resultObj, newValue);
					}
					continue;
				}

				// 2. 处理对象类型（AttachmentVo）
				if (isAttachmentVo(field.getType())) {
					String oldId = getIdFromObject(oldValue);
					String newId = getIdFromObject(newValue);
					if (ObjectUtils.isNotEmpty(oldValue) && ObjectUtils.isEmpty(newValue)) {
						field.set(resultObj, null);
					} else if (!StringUtils.equals(oldId, newId) || ( StringUtils.isBlank (oldId) && StringUtils.isNotBlank (newId) ) ) {
						field.set(resultObj, newValue);
					}
					continue;
				}

				// 3. 普通字段
				if (ObjectUtils.isNotEmpty(oldValue) && ObjectUtils.isEmpty(newValue)) {
					field.set(resultObj, "无");
				} else if (!Objects.equals(oldValue, newValue) || ( ObjectUtils.isEmpty (oldValue) && ObjectUtils.isNotEmpty (newValue) ) ) {
					field.set(resultObj, newValue);
				}
			}
			// 4. 检查结果对象是否全为 null
			if (allFieldsNull(resultObj, t)) return null;
		} catch ( Exception e ) {
			log.error ( "车间档案变更记录对比失败" , e );
			throw new RuntimeException ( "车间档案变更记录对比失败" );
		}
		return resultObj;
	}

	// 判断是否为AttachmentVo类型（可根据你的实际类型名调整）
	private static boolean isAttachmentVo(Class<?> clazz) {
		return clazz != null && clazz.getSimpleName().equals("AttachmentVo");
	}

	// 从对象中获取id字段
	private static String getIdFromObject ( Object obj ) {
		if (obj == null) return null;
		try {
			Field idField = obj.getClass().getDeclaredField("id");
			idField.setAccessible(true);
			Object idValue = idField.get(obj);
			return idValue == null ? null : idValue.toString();
		} catch (Exception e) {
			return null;
		}
	}

	// 从对象集合中提取id列表
	private static List<String> getIdListFromObjectList(List<?> list) {
		if (list == null) return Collections.emptyList();
		return list.stream()
				.map(PubDataHistoryServiceImpl::getIdFromObject)
				.filter(Objects::nonNull)
				.collect( Collectors.toList());
	}

	/**
	 * 检查对象的所有字段是否都为 null
	 * @param obj 要检查的对象
	 * @param clazz 对象的类型
	 * @return 如果所有字段都为 null 返回 true，否则返回 false
	 */
	private <T> boolean allFieldsNull(T obj, Class<T> clazz) {
		try {
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				Object value = field.get(obj);
				if (value != null) {
					return false;
				}
			}
			return true;
		} catch (IllegalAccessException e) {
			log.error("检查对象字段是否全为 null 时出错", e);
			return false;
		}
	}

}
